home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 332 / hcc / p2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-26  |  14.9 KB  |  859 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    p2.c
  12.  *
  13.  *    Expression tree routines.
  14.  *
  15.  *    Constant folding, typing of nodes, simple transformations.
  16.  */
  17.  
  18. #include <stdio.h>
  19. #include "param.h"
  20. #include "tok.h"
  21. #include "nodes.h"
  22. #include "cookie.h"
  23.  
  24. #if MMCC
  25. overlay "pass2"
  26. #endif
  27.  
  28. extern int xflags[];
  29. #define debug xflags['t'-'a']
  30.  
  31. extern nmerrors;
  32. NODEP bas_type();
  33.  
  34. do_expr(np, cookie)
  35. NODE *np;
  36. {
  37.     if (np == NULL)
  38.         return;
  39. /*    include if want only one error at a time
  40.     if (nmerrors) {
  41.         freenode(np);
  42.         return;
  43.     }
  44. */
  45.     p2_expr(&np);
  46.     genx(np, cookie);
  47. }
  48.  
  49. p2_expr(npp)
  50. NODEP *npp;
  51. {
  52.     NODEP np = *npp;
  53.  
  54.     if (np == NULL) return;
  55.     if (debug > 1) {
  56.         printf("P2 enter");
  57.         printnode(np);
  58.     }
  59.     confold(npp,0);
  60.     np = *npp;
  61.     form_types(np);
  62.     if (debug) {
  63.         printf("p2_expr");
  64.         printnode(np);
  65.     }
  66.     return;
  67. }
  68.  
  69. form_types(np)
  70. NODEP np;
  71. {
  72.  
  73.     if (np == NULL) return;
  74.     switch (np->e_type) {
  75.     case E_SPEC:
  76.         switch (np->e_token) {    /* special cases */
  77.         case '.':
  78.         case ARROW:
  79.             form_types(np->n_left);
  80.             sel_type(np);
  81.             return;
  82.         case '(':
  83.             if (np->n_right) {
  84.                 form_types(np->n_right);    /* args */
  85.                 np->e_type = E_BIN;
  86.             } else
  87.                 np->e_type = E_UNARY;
  88.             fun_type(np);
  89.             return;
  90.         }
  91.         /* fall through */
  92.     case E_BIN:
  93.         form_types(np->n_left);
  94.         form_types(np->n_right);
  95.         b_types(np);
  96.         break;
  97.  
  98.     case E_UNARY:
  99.         form_types(np->n_left);
  100.         u_types(np);
  101.         break;
  102.  
  103.     case E_LEAF:
  104.         l_types(np);
  105.         break;
  106.     }
  107. }
  108.  
  109. /* (fun) (args) */
  110. fun_type(np)
  111. NODEP np;
  112. {
  113.     NODEP lp, typ;
  114.     NODEP allsyms(), new_fun();
  115.  
  116.     lp = np->n_left;
  117.     if (lp->e_token == ID) { /* may be new ID */
  118.         typ = allsyms(lp);
  119.         if (typ == NULL)
  120.             typ = new_fun(lp);
  121.         typ = typ->n_tptr;
  122.         lp->n_tptr = typ;
  123.         lp->n_flags |= N_COPYT;
  124.     } else {
  125.         form_types(lp);
  126.         typ = lp->n_tptr;
  127.     }
  128.     if (typ->t_token != '(') {    /* fun ret ? */
  129.         error("call non-fun");
  130.         goto bad;
  131.     }
  132.     typ = typ->n_tptr;
  133.     goto good;
  134. bad:
  135.     typ = bas_type(K_INT);
  136. good:
  137.     np->n_tptr = typ;
  138.     np->n_flags |= N_COPYT;
  139. }
  140.  
  141. /* (struct|union) (. or ->) ID */
  142. sel_type(xp)
  143. NODEP xp;
  144. {
  145.     NODEP np, sup;
  146.     int tok;
  147.     NODEP rv;
  148.     NODEP llook();
  149.  
  150.     np = xp->n_right;
  151.     sup = xp->n_left->n_tptr;
  152.     tok = xp->e_token;
  153.  
  154. /* already checked that np->e_token == ID */
  155.     if (tok == ARROW) {
  156.         if (sup->t_token != STAR) {
  157.             error("(non pointer)->");
  158.             goto bad;
  159.         }
  160.         sup = sup->n_tptr;
  161.     }
  162.     if (sup->t_token != K_STRUCT && sup->t_token != K_UNION) {
  163.         error("select non-struct");
  164.         goto bad;
  165.     }
  166.     rv = llook(sup->n_right, np);
  167.     if (rv == NULL) {
  168.         error("? member ID");
  169.         goto bad;
  170.     }
  171.     xp->e_offs = rv->e_offs;
  172.     if (rv->e_fldw) {
  173.         xp->e_fldw = rv->e_fldw;
  174.         xp->e_fldo = rv->e_fldo;
  175.     }
  176.     rv = rv->n_tptr;
  177.     goto good;
  178. bad:
  179.     rv = bas_type(K_INT);
  180. good:
  181.     xp->n_tptr = rv;
  182.     xp->n_flags |= N_COPYT;
  183.  
  184.     /* change to UNARY op */
  185.     xp->e_type = E_UNARY;
  186.     freenode(np);
  187.     xp->n_right = NULL;
  188.  
  189.     /* change ARY OF to PTR TO */
  190.     if (rv->t_token == '[')
  191.         see_array(xp);
  192. }
  193.  
  194. l_types(np)
  195. register NODE *np;
  196. {
  197.     NODEP allsyms();
  198.     register NODE *tp;
  199.  
  200.     switch (np->e_token) {
  201.     case ID:    /* already did see_id */
  202.         if (np->n_tptr->t_token == '[')    /* change to &ID */
  203.             see_array(np);
  204.         return;
  205.     case ICON:
  206.         tp = bas_type(icon_ty(np));
  207.         break;
  208.     case FCON:
  209.         tp = bas_type(K_DOUBLE);
  210.         break;
  211.     case SCON:
  212.         tp = bas_type(SCON);
  213.         break;
  214.     default:
  215.         errors("Weird leaf",np->n_name);
  216.     bad:
  217.         tp = bas_type(K_INT);
  218.     }
  219.     np->n_tptr = tp;
  220.     np->n_flags |= N_COPYT;
  221. }
  222.  
  223. u_types(np)
  224. NODEP np;
  225. {
  226.     NODEP tp;
  227.     NODEP lp = np->n_left;
  228.     NODEP normalty();
  229.  
  230.     tp = lp->n_tptr;    /* default */
  231.  
  232.     switch (np->e_token) {
  233.     case DOUBLE '+':
  234.     case DOUBLE '-':
  235.     case POSTINC:
  236.     case POSTDEC:
  237.         mustlval(lp);
  238.         mustty(lp, R_SCALAR);
  239.         if (tp->t_token == STAR)
  240.             np->e_offs = tp->n_tptr->t_size;
  241.         else
  242.             np->e_offs = 1;
  243.         break;
  244.     case STAR:
  245.         if (mustty(lp, R_POINTER)) goto bad;
  246.         tp = tp->n_tptr;
  247.         np->n_tptr = tp;
  248.         np->n_flags |= N_COPYT;
  249.  
  250.         /* Ary of to Ptr to */
  251.         if (tp->t_token == '[')
  252.             see_array(np);
  253.         return;
  254.     case UNARY '&':
  255.         mustlval(lp);
  256.         tp = allocnode();
  257.         tp->n_tptr = lp->n_tptr;
  258.         tp->n_flags |= N_COPYT;
  259.         tp->t_token = STAR;
  260.         sprintf(tp->n_name, "Ptr to");
  261.         tp->t_size = SIZE_P;
  262.         np->n_tptr = tp;
  263.         return;        /* no COPYT */
  264.     case UNARY '-':
  265.         mustty(lp, R_ARITH);
  266.         tp = normalty(lp, NULL);
  267.         break;
  268.     case TCONV:
  269.         mustty(lp, R_SCALAR);
  270.         if (np->n_tptr->t_token != K_VOID)
  271.             mustty(np, R_SCALAR);
  272.         return;        /* type already specified */
  273.     case '!':
  274.         mustty(lp, R_SCALAR);
  275.         tp = bas_type(K_INT);
  276.         break;
  277.     case '~':
  278.         mustty(lp, R_INTEGRAL);
  279.         tp = normalty(lp, NULL);
  280.         break;
  281.     default:
  282.         error("bad unary type");
  283.     bad:
  284.         tp = bas_type(K_INT);
  285.     }
  286.     np->n_tptr = tp;
  287.     np->n_flags |= N_COPYT;
  288. }
  289.  
  290. b_types(np)
  291. NODEP np;
  292. {
  293.     NODEP tp;
  294.     NODEP lp, rp;
  295.     NODEP normalty(), addty(), colonty();
  296.     int op;
  297.  
  298.     op = np->e_token;
  299.     if (isassign(op)) {
  300.         mustlval(np->n_left);
  301.         op -= (ASSIGN 0);
  302.     }
  303.  
  304.     lp = np->n_left;
  305.     rp = np->n_right;
  306.     tp = bas_type(K_INT);
  307.     switch (op) {
  308.     case '*':
  309.     case '/':
  310.         mustty(lp, R_ARITH);
  311.         mustty(rp, R_ARITH);
  312.         tp = normalty(lp,rp);
  313.         break;
  314.     case '%':
  315.     case '&':
  316.     case '|':
  317.     case '^':
  318.         mustty(lp, R_INTEGRAL);
  319.         mustty(rp, R_INTEGRAL);
  320.         tp = normalty(lp,rp);
  321.         break;
  322.     case '+':
  323.     case '-':
  324.         mustty(lp, R_SCALAR);
  325.         mustty(rp, R_SCALAR);
  326.         tp = addty(np);
  327.         break;
  328.     case DOUBLE '<':
  329.     case DOUBLE '>':
  330.         mustty(lp, R_INTEGRAL);
  331.         mustty(rp, R_INTEGRAL);
  332.         tp = normalty(lp, NULL);
  333.         break;
  334.     case '<':
  335.     case '>':
  336.     case LTEQ:
  337.     case GTEQ:
  338.     case DOUBLE '=':
  339.     case NOTEQ:
  340.         mustty(lp, R_SCALAR);
  341.         mustty(rp, R_SCALAR);
  342.         chkcmp(np);
  343.         break;        /* INT */
  344.     case DOUBLE '&':
  345.     case DOUBLE '|':
  346.         mustty(lp, R_SCALAR);
  347.         mustty(rp, R_SCALAR);
  348.         break;        /* INT */
  349.     case '?':
  350.         mustty(lp, R_SCALAR);
  351.         tp = rp->n_tptr;
  352.         break;
  353.     case ':':
  354.         if (same_type(lp->n_tptr, rp->n_tptr)) {
  355.             tp = lp->n_tptr;
  356.             break;
  357.         }
  358.         mustty(lp, R_SCALAR);
  359.         mustty(rp, R_SCALAR);
  360.         tp = colonty(np);
  361.         break;
  362.     case '=':
  363.         mustlval(lp);
  364.         mustty(lp, R_ASSN);
  365.         asn_chk(lp->n_tptr, rp);
  366.         tp = lp->n_tptr;
  367.         break;
  368.     case ',':
  369.         tp = rp->n_tptr;
  370.         break;
  371.     default:
  372.         error("bad binary type");
  373.     bad:
  374.         tp = bas_type(K_INT);
  375.     }
  376.     if (isassign(np->e_token)) {
  377.         /* ignore normal result -- result is left type */
  378.         tp = lp->n_tptr;
  379.     }
  380.     np->n_tptr = tp;
  381.     np->n_flags |= N_COPYT;
  382. }
  383.  
  384. long
  385. conlval(np)
  386. NODEP np;
  387. {
  388.     long i;
  389.  
  390.     confold(&np,0);
  391.     if (np->e_token == ICON) {
  392.         i = np->e_ival;
  393.         freenode(np);
  394.         return i;
  395.     }
  396.     error("need const expr");
  397.     return 0;
  398. }
  399.  
  400. conxval(np)
  401. NODEP np;
  402. {
  403.     return (int)conlval(np);
  404. }
  405.  
  406. confold(npp,spec)
  407. NODEP *npp;
  408. {
  409.     NODEP np;
  410.     NODEP tp, onp;
  411.     int tok,spl,spr;
  412.     long l;
  413.  
  414.     np = *npp;
  415.     if (np == NULL) return;
  416.     switch (np->e_type) {
  417.     case E_LEAF:
  418.             lcanon(np,spec);
  419.             return;
  420.     case E_UNARY:
  421.             confold(&np->n_left,0);
  422.             ucanon(np);
  423.             return;
  424.     case E_BIN:
  425.             confold(&np->n_left,0);
  426.     /* delay confold on the right tree */
  427.             switch (np->e_token) {
  428.             case DOUBLE '|':
  429.                 l = np->n_left->e_ival;
  430.                 tp = np;
  431.                 goto l_or_r;
  432.             case DOUBLE '&':
  433.                 l = ! np->n_left->e_ival;
  434.                 tp = np;
  435.                 goto l_or_r;
  436.             case '?':
  437.                 l = np->n_left->e_ival;
  438.                 tp = np->n_right;    /* ':' node */
  439.         l_or_r:
  440.                 tok = np->n_left->e_token;
  441.                 if (tok != ICON) {
  442.                     confold(&np->n_right,0);
  443.                     return;
  444.                 }
  445.                 onp = np;
  446.                 if (l) {    /* take true side */
  447.                     np = tp->n_left;
  448.                     tp->n_left = NULL;
  449.                 } else {    /* take false side */
  450.                     np = tp->n_right;
  451.                     tp->n_right = NULL;
  452.                 }
  453.                 freenode(onp);
  454.                 confold(&np,0);
  455.                 *npp = np;
  456.                 return;
  457.             }
  458.             confold(&np->n_right,0);
  459.             bcanon(np);
  460.             if (np->e_flags & C_AND_A)
  461.                 b_assoc(np);
  462.             return;
  463.     case E_SPEC:
  464.         tok = np->e_token;
  465.         spl = spr = 0;
  466.         switch (tok) {
  467.         case '(':
  468.             spl = tok;    /* new name allowed */
  469.             break;
  470.         case '.':
  471.         case ARROW:
  472.             spr = tok;    /* look in struct sym.tab. */
  473.             break;
  474.         }
  475.         confold(&np->n_left,spl);
  476.         confold(&np->n_right,spr);
  477.         return;
  478.     }
  479. }
  480.  
  481. newicon(np,x,nf)
  482. NODE *np;
  483. long x;
  484. {
  485.     np->e_token = ICON;
  486.     np->e_ival = x;
  487.     np->e_flags = nf;
  488.     sprintf(np->n_name, "%ld", x);
  489.     np->e_type = E_LEAF;
  490.     if (np->n_left) {
  491.         freenode(np->n_left);
  492.         np->n_left = NULL;
  493.     }
  494.     if (np->n_right) {
  495.         freenode(np->n_right);
  496.         np->n_right = NULL;
  497.     }
  498. }
  499.  
  500. newfcon(np,x,nf)
  501. NODE *np;
  502. double x;
  503. {
  504.     np->e_token = FCON;
  505.     np->e_fval = x;
  506.     np->e_flags = nf;
  507.     sprintf(np->n_name, FLTFORM, x);
  508.     np->e_type = E_LEAF;
  509.     if (np->n_left) {
  510.         freenode(np->n_left);
  511.         np->n_left = NULL;
  512.     }
  513.     if (np->n_right) {
  514.         freenode(np->n_right);
  515.         np->n_right = NULL;
  516.     }
  517. }
  518.  
  519. /* LEAF */
  520. /* sptok is token if E_SPEC node is parent
  521.    and dont want to look at ID yet */
  522. lcanon(np,sptok)
  523. NODE *np;
  524. {
  525.     NODE *tp;
  526.     NODEP allsyms();
  527.     long x;
  528.  
  529.     if (np->e_token == ID) {
  530.         if (sptok)
  531.             return;
  532.         see_id(np);
  533.         return;
  534.     }
  535.     if (np->e_token == TSIZEOF) {
  536.         tp = np->n_tptr;
  537.         x = tp->t_size;
  538.         np->n_tptr = NULL;
  539.         if ((np->n_flags & N_COPYT) == 0)
  540.             freenode(tp);
  541.         newicon(np, x, 0);
  542.     }
  543. }
  544.  
  545. /* UNARY */
  546. ucanon(np)
  547. NODE *np;
  548. {
  549.     NODE *tp;
  550.     long x,l;
  551.     int lflags = 0;
  552.  
  553.     if (np->e_token == K_SIZEOF) {
  554.         tp = np->n_left;
  555.         confold(&tp,0);
  556.         form_types(tp);
  557.         tp = tp->n_tptr;
  558.         x = tp->t_size;
  559.         goto out;
  560.     }
  561.  
  562.     if (np->n_left->e_token == FCON) {
  563.         if (np->e_token == UNARY '-')
  564.             newfcon(np, -(np->n_left->e_fval));
  565.         return;
  566.     }
  567.     if (np->n_left->e_token != ICON)
  568.         return;
  569.     l = np->n_left->e_ival;
  570.     lflags = np->n_left->e_flags;
  571.     switch (np->e_token) {
  572.     case UNARY '-':
  573.             x = -l;        break;
  574.     case '~':
  575.             x = ~l;        break;
  576.     case '!':
  577.             x = !l;        break;
  578.     default:
  579.         return;
  580.     }
  581. out:
  582.     newicon(np, x, lflags);
  583. }
  584.  
  585. bcanon(np)
  586. register NODE *np;
  587. {
  588.     int ltok, rtok;
  589.     double l,r;
  590.     NODEP tp;
  591.  
  592.     ltok = np->n_left->e_token;
  593.     rtok = np->n_right->e_token;
  594.     if (ltok != ICON && ltok != FCON)
  595.         return;
  596.     if (rtok != ICON && rtok != FCON) {
  597.     /* left is ?CON, right is not */
  598.         if (np->e_flags & (C_AND_A|C_NOT_A)) {
  599.         /* reverse sides  - put CON on right */
  600.             tp = np->n_left;
  601.             np->n_left = np->n_right;
  602.             np->n_right = tp;
  603.             if (np->e_flags & C_NOT_A)
  604.                 swt_op(np);
  605.         }
  606.         return;
  607.     }
  608.     if (ltok == ICON && rtok == ICON) {
  609.         b2i(np);
  610.         return;
  611.     }
  612.     if (ltok == FCON)
  613.         l = np->n_left->e_fval;
  614.     else
  615.         l = (double)np->n_left->e_ival;
  616.     if (rtok == FCON)
  617.         r = np->n_right->e_fval;
  618.     else
  619.         r = (double)np->n_right->e_ival;
  620.     b2f(np,l,r);
  621. }
  622.  
  623. /* canon for assoc. & comm. op */
  624. /* this code will almost never be executed, but it was fun. */
  625. b_assoc(np)
  626. NODEP np;
  627. {
  628.     NODEP lp, rp;
  629.     int tok;
  630.  
  631.     lp = np->n_left;
  632.     if (lp->e_token != np->e_token)
  633.         return;
  634.     /* left is same op as np */
  635.     rp = np->n_right;
  636.     tok = lp->n_right->e_token;
  637.     if (tok != ICON && tok != FCON)
  638.         return;
  639.     /* left.right is ?CON */
  640.     tok = rp->e_token;
  641.     if (tok == ICON || tok == FCON) {
  642.         /* have 2 CONS l.r and r -- put together on r */
  643.         NODEP    ep;
  644.         ep = lp->n_left;
  645.         np->n_left = ep;
  646.         np->n_right = lp;
  647.         lp->n_left = rp;
  648.         /* can now fold 2 CONS */
  649.         bcanon(lp);
  650.     } else {
  651.         /* have 1 CON at l.r -- move to top right */
  652.         NODEP    kp;
  653.         kp = lp->n_right;
  654.         lp->n_right = rp;
  655.         np->n_right = kp;
  656.     }
  657. }
  658.  
  659. /* switch pseudo-commutative op */
  660. swt_op(np)
  661. NODEP np;
  662. {
  663.     int newtok;
  664.     char *newnm;
  665.  
  666.     switch (np->e_token) {
  667.     case '<':    newtok = '>';    newnm = ">";    break;
  668.     case '>':    newtok = '<';    newnm = "<";    break;
  669.     case LTEQ:    newtok = GTEQ;    newnm = ">=";    break;
  670.     case GTEQ:    newtok = LTEQ;    newnm = "<=";    break;
  671.     default:
  672.         return;
  673.     }
  674.     np->e_token = newtok;
  675.     strcpy(np->n_name, newnm);
  676. }
  677.  
  678. /* BINARY 2 ICON's */
  679. b2i(np)
  680. register NODE *np;
  681. {
  682.     register long l,r,x;
  683.     int newflags,lflags;
  684.  
  685.     newflags = 0;
  686.  
  687.     r = np->n_right->e_ival;
  688.     newflags = np->n_right->e_flags;
  689.  
  690.     l = np->n_left->e_ival;
  691.     lflags = np->n_left->e_flags;
  692.     newflags = newflags>lflags ? newflags : lflags;
  693.  
  694.     switch (np->e_token) {
  695.     case '+':
  696.             x = l+r;    break;
  697.     case '-':
  698.             x = l-r;    break;
  699.     case '*':
  700.             x = l*r;    break;
  701.     case '/':
  702.             x = l/r;    break;
  703.     case '%':
  704.             x = l%r;    break;
  705.     case '>':
  706.             x = l>r;    break;
  707.     case '<':
  708.             x = l<r;    break;
  709.     case LTEQ:
  710.             x = l<=r;    break;
  711.     case GTEQ:
  712.             x = l>=r;    break;
  713.     case DOUBLE '=':
  714.             x = l==r;    break;
  715.     case NOTEQ:
  716.             x = l!=r;    break;
  717.     case '&':
  718.             x = l&r;    break;
  719.     case '|':
  720.             x = l|r;    break;
  721.     case '^':
  722.             x = l^r;    break;
  723.     case DOUBLE '<':
  724.             x = l<<r;    break;
  725.     case DOUBLE '>':
  726.             x = l>>r;    break;
  727.     default:
  728.         return;
  729.     }
  730.     newicon(np, x, newflags);
  731. }
  732.  
  733. /* BINARY 2 FCON's */
  734. b2f(np,l,r)
  735. register NODE *np;
  736. double l,r;
  737. {
  738.     register double x;
  739.     int ix, isint;
  740.  
  741.     isint = 0;
  742.  
  743.     switch (np->e_token) {
  744.     case '+':
  745.             x = l+r;    break;
  746.     case '-':
  747.             x = l-r;    break;
  748.     case '*':
  749.             x = l*r;    break;
  750.     case '/':
  751.             x = l/r;    break;
  752.     case '>':
  753.             ix = l>r;    isint++;    break;
  754.     case '<':
  755.             ix = l<r;    isint++;    break;
  756.     case LTEQ:
  757.             ix = l>=r;    isint++;    break;
  758.     case GTEQ:
  759.             ix = l<=r;    isint++;    break;
  760.     case DOUBLE '=':
  761.             ix = l==r;    isint++;    break;
  762.     case NOTEQ:
  763.             ix = l!=r;    isint++;    break;
  764.     default:
  765.         return;
  766.     }
  767.     if (isint)
  768.         newicon(np, (long)ix, 0);
  769.     else
  770.         newfcon(np, x);
  771. }
  772.  
  773. same_type(a,b)
  774. register NODE *a, *b;
  775. {
  776. more:
  777.     if (a == b)
  778.         return 1;
  779.     if (a == NULL || b == NULL)
  780.         return 0;
  781.     if (a->t_token != b->t_token)
  782.         return 0;
  783.     if (a->t_token != STAR && a->t_size != b->t_size)
  784.         return 0;
  785.     a = a->n_tptr;
  786.     b = b->n_tptr;
  787.     goto more;
  788. }
  789.  
  790. see_id(np)
  791. NODEP np;
  792. {
  793.     NODEP tp;
  794.     NODEP allsyms(), def_type();
  795.  
  796.     tp = allsyms(np);
  797.     if (tp == NULL) {
  798.         errorn("undefined:", np);
  799.         tp = def_type();
  800.         goto out;
  801.     }
  802.     switch (tp->e_sc) {
  803.     case ENUM_SC:
  804.         newicon(np, tp->e_ival, 0);
  805.         return;
  806.     case K_REGISTER:
  807.         np->e_rno = tp->e_rno;
  808.         /* fall through */
  809.     default:
  810.         np->e_sc = tp->e_sc;
  811.         np->e_offs = tp->e_offs;
  812.         tp = tp->n_tptr;
  813.     }
  814. out:
  815.     np->n_tptr = tp;
  816.     np->n_flags |= N_COPYT;
  817.  
  818.     /* special conversions */
  819.     if (tp->t_token == '(')
  820.         insptrto(np);
  821. }
  822.  
  823. insptrto(np)
  824. NODEP np;
  825. {
  826.     NODEP op, copyone();
  827.  
  828.     op = copyone(np);
  829.  
  830.     np->n_left = op;
  831.     np->e_token = UNARY '&';
  832.     np->e_type = E_UNARY;
  833.     strcpy(np->n_name, "&fun");
  834.     np->n_flags &= ~N_COPYT;
  835. }
  836.  
  837. /* np points to ID or STAR or '.' node
  838.     tptr is a COPY
  839.     tptr token is '[' */
  840.  
  841. see_array(np)
  842. NODEP np;
  843. {
  844.     NODEP tp, copyone();
  845.  
  846.     tp = copyone(np);
  847.     tp->n_left = np->n_left;
  848.     tp->n_tptr = tp->n_tptr->n_tptr;
  849.  
  850.     np->n_left = tp;
  851.     np->e_token = UNARY '&';
  852.     np->e_type = E_UNARY;
  853.     strcpy(np->n_name, "&ary");
  854.     arytoptr(np);
  855. /* leave old size
  856.     np->n_tptr->t_size = SIZE_P;
  857. */
  858. }
  859.